package ExpressTwo;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class FirstInFirstOut {
    private final MainInterface _D;

    FirstInFirstOut(MainInterface d) {
        _D = d;
    }

    //更改FIFO的内容
    void change() {
        change_center();
    }

    void change_center() {
        //左边是8个标签，
        //分别是：0 块号，1 物理地址，2 是否缺页，3 是否置换，4 缺页次数，5 置换次数，6 缺页率，7 置换率

        JTable table = _D.getFifo_table1();
        //中间是表格的东西，表格分别含有：0 页号，1 块号，2 状态
        //需要根据，计算出来的页号，然后从位示图中读取一个存储位置，然后放置相应的位置
        int page = _D.logicAddress / (_D.blockSize * 1024);
        int blockID;
        //设置块号
        if ("0".equals(table.getValueAt(page, 2))) {
            //如果是缺页
            //Node saved = _D.list_fifo.removeHead();
            if (_D.list_bitMapFIFO.getLength() != 0) {
                //块未满
                blockID = _D.list_bitMapFIFO.removeHead();//从位示图中选择
                JTable bit = _D.getBitMap_table();
                bit.setValueAt("1", blockID / table.getColumnCount(), blockID % table.getColumnCount());

                table.setValueAt(blockID, page, 1);//设置块号
                table.setValueAt("1", page, 2);//设置状态
                _D.list_fifo.add(new Node(page, blockID));//把这一队添加到该队列中
                _D.fifoNeedPage++;
                //更新状态

                _D.setLabels_fifo(2, "是");
                _D.setLabels_fifo(3, "否");

            } else {
                //块已用满
                //取消旧的状态
                Node saved = _D.list_fifo.removeHead();
                table.setValueAt("0", saved.page, 2);//设置状态
                table.setValueAt("", saved.page, 1);//设置块号

                //更新状态
                table.setValueAt("1", page, 2);//设置状态
                table.setValueAt(String.valueOf(saved.block), page, 1);//设置块号
                _D.list_fifo.add(new Node(page, saved.block));

                _D.fifoNeedPage++;//缺页次数增加
                _D.fifoNeedChange++;//置换次数增加
                //更新状态

                _D.setLabels_fifo(2, "是");
                _D.setLabels_fifo(3, "是");
            }
            //更新状态
            _D.setLabels_fifo(0, String.valueOf(table.getValueAt(page, 1)));//设置块号

            int pos = (Integer.parseInt(String.valueOf(table.getValueAt(page, 1)))) * 1024 + _D.pageAddress;
            _D.setLabels_fifo(1, "0x " + Integer.toHexString(pos) + "H");

        } else {
            //不是缺页
            //直接更新状态
            _D.setLabels_fifo(0, String.valueOf(table.getValueAt(page, 1)));//设置块号
            int pos = Integer.parseInt(String.valueOf(table.getValueAt(page, 1))) * 1024 + _D.pageAddress;
            _D.setLabels_fifo(1, "0x " + Integer.toHexString(pos) + "H");
            _D.setLabels_fifo(2, "否");
            _D.setLabels_fifo(3, "否");

        }

        _D.setLabels_fifo(4, String.valueOf(_D.fifoNeedPage));
        _D.setLabels_fifo(5, String.valueOf(_D.fifoNeedChange));
        _D.setLabels_fifo(6, (((double) _D.fifoNeedPage) / _D.accessCount) * 100 + " %");
        _D.setLabels_fifo(7, (((double) _D.fifoNeedChange) / _D.accessCount) * 100 + " %");
        //记录页号顺序
        change_right(page);
    }

    //更改右边部分
    void change_right(int page) {
        //先进先出置换流程
        boolean flag = false;
        DefaultTableModel d = (DefaultTableModel) _D.getFifo_table2().getModel();
        for (int i = 0; i < _D.stack_fifo.getLength(); i++) {
            if (_D.stack_fifo.get(i) == page) {
                flag = true;
                break;
            }
        }

        if (!flag) {
            //如果没有找到，那么就把其头去掉，从尾部增加一个值
            if (_D.stack_fifo.getLength() == _D.blockNumber)
                _D.stack_fifo.removeHead();
            _D.stack_fifo.add(page);
        }
        //下面是显示内容
        String[] show = {"", "", "", ""};
        show[0] = String.valueOf(d.getRowCount());
        show[1] = String.valueOf(page);
        for (int i = 0; i < _D.stack_fifo.getLength(); i++) {
            show[2] = show[2] + " " + _D.stack_fifo.get(i) + " ";
        }
        if (!flag) {
            show[3] = "√";
        } else {
            show[3] = "×";
        }
        d.addRow(show);

    }

}
